package cz.uhk.max.util;

import java.io.PrintStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class SelectBooleanDataScroller extends DataScroller {

	private static final long serialVersionUID = 342949797497311793L;
	
	private boolean allChecked;
	private Map<Integer, Set<Integer>> checkedIndexes;

	
	public SelectBooleanDataScroller() {		
		this (DEFAULT_BUNDLE);		
	}
	
	public SelectBooleanDataScroller(int bundle) {
		super(bundle);
		checkedIndexes = new HashMap<Integer, Set<Integer>>();
		allChecked = false;
	}

	public void setPageSet(Integer page, Set<Integer> checkedPohledavkasPage) {
		checkedIndexes.put(page, checkedPohledavkasPage);
	}
	
	public void addCheckedValue(Integer page, Integer position) {
		Set<Integer> checked = checkedIndexes.get(page);
		if (checked == null) {
			checked = new HashSet<Integer>();
			checkedIndexes.put(page, checked);
		}
		checked.add(position);
	}
	
	public boolean isValueChecked(Integer page, Integer position) {
		Set<Integer> checked = checkedIndexes.get(page);
		for (Integer integer: checked) {
			if (integer.equals(position)) {
				return true;
			}
		}
		return false;
	}
	
	public int getSelectedIndexesCount() {		
		int size = 0;
		int lastPage = getLastPage();
		for (int i = 0; i <= lastPage; i++) {
			Set<Integer> set = getCheckedIndexesForPage(i);
			if (set != null) {				
				size += set.size();
			}			
		}
		return size;		
	}
	
	public int[] getSelectedIndexes() {
		int size = getSelectedIndexesCount();
		int[] selectedIndexes = new int[0]; 
		
		if (size > 0) {
			selectedIndexes = new int[size];
			Integer lastPage = getLastPage();
			int index = 0;			
			for (int i = 0; i <= lastPage; i++) {
				Set<Integer> set = getCheckedIndexesForPage(i);
				if (set != null) {
					for (Integer integer: set) {						
						selectedIndexes[index++] = i * getBundle() + integer;
					}
				}
			}
		}
		
		return selectedIndexes;
	}
	
	public void logInfo(PrintStream out) {
		for (Integer integer: checkedIndexes.keySet()) {
			out.print(integer + " - ");
			for (Integer index: checkedIndexes.get(integer)) {					
				out.print(index + " ");
			}
			out.println();
		}
	}
	
	public void removeCheckedValue(Integer page, Integer position) {
		if (page < checkedIndexes.size()) {
			Set<Integer> checked = checkedIndexes.get(page);
			if (checked != null) {				
				checked.remove(position);
			}
		}
	}
	
	@Override
	public void setCount(Integer count) {		
		if (this.count > count) {
			int pages = (count / bundle) - 1;
			int indexesAtNextPage = count % bundle;
			if (indexesAtNextPage > 0) {
				pages++;
			}
			int lastPage = getLastPage();
			for (int i = pages; i <= lastPage; i++) {
				int firstIndex = 0;
				if (i == pages) {
					firstIndex = indexesAtNextPage;
					int lastPageIndex = getPageItemsCount(i);
					for (int j = firstIndex; j <= lastPageIndex; j++) {
						removeCheckedValue(i, j);
					}
				} else {
					checkedIndexes.remove(i);					
				}
			}
		}
		super.setCount(count);
	}
	
	public void setAllChecked() {
		allChecked = true;
		int lastPage = getLastPage();
		for (int i = 0; i <= lastPage; i++) {
			int pageItemCount = getPageItemsCount(i);
			for (int j = 0; j < pageItemCount; j++) {
				addCheckedValue(i, j);
			}
		}
	}
	
	public void setUnCheckedPage(Integer page) {
		if (page < checkedIndexes.size()) {
			for (int i = 0; i < bundle; i++) {
				removeCheckedValue(page, i);
			}
		}
	}
	
	public void setAllUnChecked() {
		allChecked = false;
		for (Integer integer: checkedIndexes.keySet()) {
			checkedIndexes.get(integer).clear();
		}
	}
	
	public Set<Integer> getCheckedIndexesForPage(Integer page) {
		return checkedIndexes.get(page);
	}
	
	public void setCheckedIndexes(Map<Integer, Set<Integer>> checked) {
		this.checkedIndexes = checked;
	}
	
	public Map<Integer, Set<Integer>> getCheckedIndexes() {
		return checkedIndexes;
	}
	
	public Boolean isAllChecked() {
		return allChecked;
	}
	
}
